﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CSM_SQL.DAL
{
    internal class EmpDAL
    {
        private CSMDataBaseDataContext _data;

        public CSMDataBaseDataContext Data
        {
            get
            {
                if (_data == null || !_data.DatabaseExists())
                    _data = new CSMDataBaseDataContext(ConfigurationManager.ConnectionStrings["Constr"].ToString());
                return _data;
            }
        }

        internal List<Emp> All()
        {
            return Data.Emp.ToList();
        }

        internal Boolean Add(Emp emp)
        {
            try
            {
                var temp = from e in Data.Emp select e.E_ID;
                if (!(temp.Count() > 0))
                    emp.E_ID = 0;
                else
                    emp.E_ID = temp.Max() + 1;
                Data.Emp.InsertOnSubmit(emp);
                Data.SubmitChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return true;

        }

        internal Boolean ChangeState(int ID, int state)
        {
            var target = (from e in Data.Emp where e.E_ID == ID select e).First();
            try
            {
                target.State = state;
                Data.SubmitChanges();
            }
            catch { }
            return true;
        }

        internal Boolean Edit(Emp emp)
        {
            try
            {
                var target = (from e in Data.Emp where emp.E_ID == e.E_ID select e).First();
                target.Name = emp.Name;
                target.Password = emp.Password;
                target.Phone = emp.Phone;
                Data.SubmitChanges();
            }
            catch (Exception ex) { throw ex; }
            return true;
        }

        internal List<Emp_Ord> GetOrder(int ID)
        {
            List<Emp_Ord> orders = new List<Emp_Ord>();
            var order = from o in Data.Order join g in Data.Goods on o.G_ID equals g.G_ID where o.Temp == 0 && o.State > 0 && ID == o.TransID join c in Data.Customer on o.C_ID equals c.C_ID select new { o, g, c };

            foreach (var o in order)
            {
                OrderMes ord = new OrderMes { order = o.o, goods = o.g, customer = o.c };
                var eo = ord.TransEmpOrd();
                if (o.o.State >= 3)
                {
                    var assess = (from a in Data.Assess where a.ID == o.o.ID select a).First();
                    eo.grade = assess.Grade;
                    eo.assess = assess.Assess1;
                }
                orders.Add(eo);
            }
            return orders;
        }

        internal List<AssessMsg> GetAssess()
        {
            List<AssessMsg> orders = new List<AssessMsg>();
            var order = from o in Data.Order join g in Data.Goods on o.G_ID equals g.G_ID where o.State >= 3 join c in Data.Customer on o.C_ID equals c.C_ID select new { o, g, c };

            foreach (var o in order)
            {
                OrderMes ord = new OrderMes { order = o.o, goods = o.g, customer = o.c };
                if (ord.order.Temp != 0)
                {
                    var poster = (from p in Data.Customer join oo in Data.Order on p.C_ID equals oo.C_ID select p).First();
                    ord.postName = poster.Name;
                    ord.postPhone = poster.Phone;
                }
                else
                {
                    var poster = (from p in Data.Emp join oo in Data.Order on p.E_ID equals oo.C_ID select p).First();
                    ord.postName = poster.Name;
                    ord.postPhone = poster.Phone;
                }
                var eo = ord.TransAssMsg();


                var assess = (from a in Data.Assess where a.ID == o.o.ID select a);
                if (assess.Count() > 0)
                {
                    eo.grade = assess.First().Grade;
                    eo.assess = assess.First().Assess1;
                }

                orders.Add(eo);
            }
            return orders;
        }

        internal Boolean Send(int id)
        {
            try
            {
                var target = (from o in Data.Order where o.ID == id && o.State == 1 select o).First();
                target.State = 2;
                Data.SubmitChanges();
            }
            catch { }
            return true;
        }

        internal Boolean ChangePwd(Emp emp)
        {
            try
            {
                var target = (from e in Data.Emp where emp.E_ID == e.E_ID select e).First();
                target.Password = emp.Password;
                Data.SubmitChanges();
            }
            catch (Exception ex) { throw ex; }
            return true;
        }

        internal List<Apply> GetApply()
        {
            var ord = from o in Data.Order join c in Data.Customer on o.C_ID equals c.C_ID where o.Temp == 1 && o.State == 0 join t in Data.Customer on o.TransID equals t.C_ID into q from qqq in q.DefaultIfEmpty() select new { o, c, t = (qqq ?? null) };
            List < Apply > list = new List<Apply>();
            foreach(var o in ord)
            {
                Apply a = new Apply
                {
                    o_id = o.o.ID,
                    C_Name = o.c.Name,
                    C_Address = o.c.Address,
                    T_Address = o.t.Address,
                    T_Name = o.t.Name,
                    T_Phone = o.t.Phone
                };
                list.Add(a);

            }
            return list;
        }

        internal Boolean Reply(int id,int val)
        {
            try
            {
                var ord = Data.Order.Where(o => o.ID == id).First();
                if (val == 0)
                {
                    if (ord.Temp == 1 && ord.State == 0)
                    {
                        ord.State = 1;
                        ord.TransID = id;
                        ord.TempTime = DateTime.Now;
                    }
                }
                else
                    if (ord.Temp == 1 && ord.State == 0)
                {
                    ord.Temp = 0;
                }
                Data.SubmitChanges();
            }
            catch(Exception ex)
            {
                throw ex;
            }
            return true;
        }

        internal List<Income> getIncomeTable(DateTime startTime,DateTime endTime)
        {
            
            return Data.Income.Where(d => d.Date >= startTime && d.Date <= endTime.AddDays(1)).ToList(); ;
        }

        static internal void Timer()
        {
            EmpDAL e = new EmpDAL();
            TimeSpan span = new TimeSpan(1, 0, 0);
            while (true)
            {
                if (DateTime.Now.Minute  == 0)
                {
                    var tasks = from o in e.Data.Order where o.State == 0 || (o.Temp == 1 && o.State==1&& (DateTime.Now - o.TempTime > span)) select o;
                    foreach(var t in tasks)
                    {
                        if(t.State == 0 || t.Temp == 1)
                        {
                            var poster = e.Data.Emp.Where(a => a.Orders == e.Data.Emp.Min(o => o.Orders)).First();
                            var ts = tasks.Where(a => (a.State == 0 || a.Temp == 1) && a.C_ID == t.C_ID);
                                foreach (var q in ts)
                                {
                                    q.State = 1;
                                    q.Temp = 0;
                                    q.TempTime = DateTime.Now;
                                    q.TransID = poster.E_ID;
                                    poster.Orders++;
                                }
                        }
                        
                    }
                   
                    e.Data.SubmitChanges();
                    Thread.Sleep(span);
                }
            }
        }
    }
}
